package com.spring.arch.datasource.core.helper;

import com.alibaba.druid.pool.DruidDataSource;
import com.spring.arch.datasource.core.context.DatasourceParamConfig;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 提供对应的数据源
 *
 * @author Frank
 * @since 2019/12/7 01:13
 */
@Slf4j
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class InstanceDataSourceProvider {

    private static Map<String, DataSource> schemaMap = new ConcurrentHashMap<>();
    private static Map<String, String> projectIdSchemaCodeMap = new ConcurrentHashMap<>();

    private static final Object LOCK = new Object();

    /**
     * 获取数据源
     * @param instanceId 实例Id
     */
    public static DataSource getInstanceDataSource(String instanceId) {
        log.info("获取缓存数据源信息|enter, 数据源id=[{}]", instanceId);
        if (!schemaMap.containsKey(instanceId)) {
            log.warn("获取缓存数据源信息|[{}]不存在", instanceId);
            return null;
        }
        return schemaMap.get(instanceId);
    }

    /**
     * 获取数据源SchemaCode
     * @param projectId 项目Id
     */
    public static String getSchemaByProjectId(String projectId) {
        return projectIdSchemaCodeMap.get(projectId);
    }

//    /**
//     * 添加数据源
//     * @param config 数据源配置
//     */
//    public static DataSource addDataSource(DatasourceParamConfig config) {
//        String schemaCode = config.getSchemaName();
//        String instanceConnectionPoolName = schemaCode + "-connection-pool";
//        synchronized (LOCK) {
//            if (!schemaMap.containsKey(schemaCode)) {
//                HikariDataSource dataSource = new HikariDataSource();
//                dataSource.setUsername(config.getUsername());
//                dataSource.setPassword(config.getPassword());
//                dataSource.setJdbcUrl(config.getUrl());
//                dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
//                dataSource.setMinimumIdle(10);
//                dataSource.setMaximumPoolSize(10);
//                dataSource.setConnectionTimeout(60000);
//                dataSource.setIdleTimeout(30000);
//                dataSource.setMaxLifetime(1800000);
//                dataSource.setValidationTimeout(10000);
//                dataSource.setPoolName(instanceConnectionPoolName);
//                schemaMap.put(schemaCode, dataSource);
//                projectIdSchemaCodeMap.put(String.valueOf(config.getProjectId()), schemaCode);
//                log.info("configuration instance datasource[{}], Connection pool name:{}", config.getSchemaName(), instanceConnectionPoolName);
//                return dataSource;
//            }
//        }
//        log.info("load instance datasource[{}], Connection pool name:{}", config.getSchemaName(), instanceConnectionPoolName);
//        return schemaMap.get(schemaCode);
//    }

    /**
     * 添加数据源
     * @param config 数据源配置
     */
    public static DataSource addDataSource(DatasourceParamConfig config) {
        String schemaCode = config.getSchemaName();
        String instanceConnectionPoolName = schemaCode + "-connection-pool";
        synchronized (LOCK) {
            if (!schemaMap.containsKey(schemaCode)) {
                DruidDataSource druidDataSource = new DruidDataSource();
                druidDataSource.setUsername(config.getUsername());
                druidDataSource.setPassword(config.getPassword());
                druidDataSource.setUrl(config.getUrl());
                druidDataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
                druidDataSource.setMaxActive(100);
                druidDataSource.setMinIdle(10);
                druidDataSource.setInitialSize(10);
                druidDataSource.setMaxWait(600000);
                druidDataSource.setMinEvictableIdleTimeMillis(300000);
                druidDataSource.setTimeBetweenEvictionRunsMillis(60000);
                druidDataSource.setRemoveAbandoned(true);
                druidDataSource.setRemoveAbandonedTimeoutMillis(1800);
                druidDataSource.setTestWhileIdle(true);
                druidDataSource.setTestOnBorrow(true);
                druidDataSource.setTestOnReturn(false);
//                HikariDataSource dataSource = new HikariDataSource();
//                dataSource.setUsername(config.getUsername());
//                dataSource.setPassword(config.getPassword());
//                dataSource.setJdbcUrl(config.getUrl());
//                dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
//                dataSource.setMinimumIdle(10);
//                dataSource.setMaximumPoolSize(10);
//                dataSource.setConnectionTimeout(60000);
//                dataSource.setIdleTimeout(30000);
//                dataSource.setMaxLifetime(1800000);
//                dataSource.setValidationTimeout(3000);
//                dataSource.setPoolName(instanceConnectionPoolName);
                schemaMap.put(schemaCode, druidDataSource);
                projectIdSchemaCodeMap.put(String.valueOf(config.getProjectId()), schemaCode);
                log.info("configuration instance datasource[{}], Connection pool name:{}", config.getProjectId(), instanceConnectionPoolName);
                return druidDataSource;
            }
        }
        log.info("load instance datasource[{}], Connection pool name:{}", config.getProjectId(), instanceConnectionPoolName);
        return schemaMap.get(schemaCode);
    }
}